home *** CD-ROM | disk | FTP | other *** search
/ The World's Largest Collection of Windows Software / The World's Largest Collection of Windows Software - Disc 1.iso / connect / _j2 / wvnsc926 / rcs / wvtxtblk.c < prev    next >
C/C++ Source or Header  |  1994-09-21  |  13KB  |  498 lines

  1. head     1.5;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.5
  10. date     94.09.18.22.42.58;  author jcooper;  state Exp;
  11. branches ;
  12. next     1.4;
  13.  
  14. 1.4
  15. date     94.09.16.01.12.35;  author jcooper;  state Exp;
  16. branches ;
  17. next     1.3;
  18.  
  19. 1.3
  20. date     94.08.11.00.11.55;  author jcooper;  state Exp;
  21. branches ;
  22. next     1.2;
  23.  
  24. 1.2
  25. date     94.05.23.18.36.00;  author jcooper;  state Exp;
  26. branches ;
  27. next     1.1;
  28.  
  29. 1.1
  30. date     94.01.16.12.12.47;  author jcoop;  state Exp;
  31. branches ;
  32. next     ;
  33.  
  34.  
  35. desc
  36. @jcoop's block mem mgmt routines, alternative to MRR's block/doc paradigm
  37. @
  38.  
  39.  
  40. 1.5
  41. log
  42. @Added IsBusy flag
  43. @
  44. text
  45. @/********************************************************************
  46.  *                                                                  *
  47.  *  MODULE    :  WVTXTBLK.C                                         *
  48.  *                                                                  *
  49.  *  PURPOSE   : This file contains Memory Management routines for   *
  50.  *        text blocks                                         *                                 
  51.  *                                                                  *
  52.  *              The TypTextBlock struct is defined in wvglob.h      *
  53.  *                                                                  *
  54.  * Author: John S. Cooper (jcooper@@netcom.com)                      *
  55.  *   Date: Sept 30, 1993                                            *
  56.  ********************************************************************/
  57. /* 
  58.  * $Id: wvtxtblk.c 1.4 1994/09/16 01:12:35 jcooper Exp $
  59.  * $Log: wvtxtblk.c $
  60.  * Revision 1.4  1994/09/16  01:12:35  jcooper
  61.  * general cleanup for 92.6
  62.  * 
  63.  * Revision 1.3  1994/08/11  00:11:55  jcooper
  64.  * Changes to author mail address
  65.  *
  66.  * Revision 1.2  1994/05/23  18:36:00  jcooper
  67.  * new attach code, session [dis]connect
  68.  *
  69.  * Revision 1.1  1994/01/16  12:12:47  jcoop
  70.  * Initial revision
  71.  *
  72.  */
  73. #include <windows.h>
  74. #include <windowsx.h>
  75. #include "wvglob.h"
  76. #include "winvn.h"
  77. #pragma hdrstop
  78. #include <stdio.h>
  79. #include <stdlib.h>
  80. #include <string.h>
  81. #include <ctype.h>
  82.  
  83. #define BLOCK_NUM_LINES_INC    64
  84. #define TEXT_SIZE_INC        1024
  85.  
  86. // Private functions
  87. BOOL IncreaseTextSize (TypTextBlock *textBlock, unsigned long inc);
  88. BOOL AllocTextBlock (TypTextBlock *textBlock);
  89.  
  90. /* ------------------------------------------------------------------------
  91.  *     Mem Management routines for text block
  92.  *    This is my simple alternative M. Riordan's Doc paradigm
  93.  */
  94. TypTextBlock *
  95. InitTextBlock (HWND hParentWnd) 
  96. {
  97.     TypTextBlock *textBlock;
  98.         
  99.     if ((textBlock = (TypTextBlock *) GlobalAllocPtr (GMEM_MOVEABLE, sizeof (TypTextBlock)))==NULL)
  100.     {
  101.         MessageBox (hParentWnd, "Memory Allocation Failure", "Text Block Create-Block", ID_OK);
  102.         return (NULL);
  103.     }
  104.     textBlock->hTextWnd = hParentWnd;
  105.     textBlock->IsBusy = TRUE;
  106.     if (AllocTextBlock(textBlock) == FAIL)
  107.         return (NULL);
  108.     
  109.     return (textBlock);
  110. }     
  111.  
  112. void
  113. ResetTextBlock (TypTextBlock *textBlock) 
  114. {
  115.     GlobalFreePtr (textBlock->text);
  116.     GlobalFreePtr (textBlock->offset);
  117.     AllocTextBlock(textBlock);
  118. }     
  119.  
  120. BOOL
  121. AllocTextBlock (TypTextBlock *textBlock)
  122. {
  123.     textBlock->maxLines = BLOCK_NUM_LINES_INC;
  124.     if ((textBlock->offset = (unsigned long huge *) GlobalAllocPtr (GMEM_MOVEABLE, textBlock->maxLines * sizeof (unsigned long huge))) == NULL)
  125.     {
  126.         MessageBox (textBlock->hTextWnd, "Memory Allocation Failure", "Text Block Create-Offsets", ID_OK);
  127.         return (FAIL);
  128.     }
  129.     textBlock->numLines = 0;
  130.  
  131.     textBlock->maxBytes = TEXT_SIZE_INC;
  132.     if ((textBlock->text = (char huge *) GlobalAllocPtr (GMEM_MOVEABLE, textBlock->maxBytes * sizeof (char huge))) == NULL)
  133.     {
  134.         MessageBox (textBlock->hTextWnd, "Memory Allocation Failure", "Text Block Create-Text", ID_OK);
  135.         return (FAIL);
  136.     }
  137.     textBlock->numBytes = 0;
  138.     textBlock->maxLineLen = 0;
  139.     return (SUCCESS);
  140. }
  141. void
  142. FreeTextBlock (TypTextBlock *textBlock)
  143. {
  144.     GlobalFreePtr (textBlock->text);
  145.     GlobalFreePtr (textBlock->offset);
  146.     GlobalFreePtr (textBlock);
  147. }
  148.  
  149. BOOL
  150. AddLineToTextBlock (TypTextBlock *textBlock, char *line)
  151. {        
  152.     unsigned int len;
  153.     unsigned long nextSeg;
  154.  
  155.     if (line == NULL || *line == '\0')
  156.         return (SUCCESS);
  157.  
  158.     // manage offset list
  159.     if (textBlock->numLines + 1 >= textBlock->maxLines)
  160.     {
  161.         textBlock->maxLines += BLOCK_NUM_LINES_INC;
  162.         if ((textBlock->offset = (unsigned long huge *) GlobalReAllocPtr (textBlock->offset,
  163.                     textBlock->maxLines * sizeof (unsigned long huge), GMEM_MOVEABLE)) == NULL)
  164.         {
  165.             MessageBox (textBlock->hTextWnd, "Memory Allocation Failure", "Text Block Add-Offsets", ID_OK);
  166.             return (FAIL);
  167.         }
  168.     }
  169.  
  170.     // manage text string
  171.     len = strlen (line) + 1;    // include the NULL in the count
  172.     if (textBlock->numBytes + len >= textBlock->maxBytes)
  173.         if (IncreaseTextSize (textBlock, max(len, TEXT_SIZE_INC)) == FAIL)
  174.             return (FAIL);
  175.         
  176.     // check if this line would cause text to cross a 64k segment
  177.     // if so, fill in with nulls, and start new line at next seg 
  178.     // WHY DO I HAVE TO DO THIS?!?!? Windows is supposed to take
  179.     // care of this isn't it?!  memcpy is supposed to work with huge
  180.     nextSeg = ((textBlock->numBytes + 65536L) / 65536L) * 65536L;
  181.     if (textBlock->numBytes + len > nextSeg) 
  182.     {
  183.        if (nextSeg + len > textBlock->maxBytes)    // do we need to add some space?
  184.            if (IncreaseTextSize (textBlock, max(nextSeg-textBlock->numBytes, TEXT_SIZE_INC)) == FAIL)
  185.             return (FAIL);
  186.        while (textBlock->numBytes < nextSeg)
  187.         textBlock->text[(textBlock->numBytes)++] = '\0';
  188.     }    
  189.         // set pointer offset to this new string
  190.         textBlock->offset[textBlock->numLines] = textBlock->numBytes;
  191.         
  192.         // copy it in, including the NULL
  193.     memcpy ((char huge *) &(textBlock->text[textBlock->numBytes]), line, len);
  194.  
  195.         // increment counters
  196.     textBlock->numLines++;
  197.     textBlock->numBytes += (unsigned long)len;
  198.     
  199.     // save max string len for use in scroll bar ranges in status wnd
  200.     if (len > textBlock->maxLineLen)
  201.         textBlock->maxLineLen = len;
  202.  
  203.     return (SUCCESS);
  204. }
  205.  
  206. BOOL
  207. IncreaseTextSize (TypTextBlock *textBlock, unsigned long inc)
  208. {
  209.     textBlock->maxBytes += inc;
  210.     if ((textBlock->text = (char huge *) GlobalReAllocPtr (textBlock->text,
  211.                 textBlock->maxBytes * sizeof (char huge), GMEM_MOVEABLE)) == NULL)
  212.     {
  213.         MessageBox (textBlock->hTextWnd, "Memory Allocation Failure", "Text Block Add-Text", ID_OK);
  214.         return (FAIL);
  215.     }
  216. }
  217. /* ------------------------------------------------------------------------
  218.  * AddEndedLineToAttach
  219.  * Front end to AddLineToTextBlock which sets the end-of-line chars
  220.  * Also, if posting and first char is '.', change it to '..'
  221.  * To add blank line, send line parameter as ""
  222.  */                   
  223. BOOL
  224. AddEndedLineToTextBlock (TypTextBlock *textBlock, char *line, int mode)
  225. {
  226.     char *new, *ptr;
  227.     unsigned int len;
  228.     BOOL result;
  229.     
  230.     len = strcspn (line, "\n\r");
  231.     ptr = new = (char *) GlobalAllocPtr (GMEM_MOVEABLE, (len+4) * sizeof(char));
  232.     if (mode == ADD_TO_POST && line[0] == '.')
  233.         *(ptr++) = '.';
  234.  
  235.     if (len > 0)
  236.         memcpy (ptr, line, len);
  237.         
  238.     switch (mode)
  239.     {
  240.     case ADD_TO_POST:
  241.         ptr[len++] = '\r';    
  242.         break;
  243.     case ADD_TO_EDIT:
  244.     case ADD_TO_FILE:
  245.         ptr[len++] = '\r';    // to edit buf
  246.         ptr[len++] = '\n';
  247.         break;
  248. //    case ADD_TO_FILE:
  249. //        ptr[len++] = '\n';
  250. //        break;
  251.     }    
  252.     ptr[len] = '\0';
  253.     
  254.     result = AddLineToTextBlock (textBlock, new);
  255.     GlobalFreePtr (new);
  256.     
  257.     return (result);
  258. }
  259.  
  260. /* ------------------------------------------------------------------------
  261.  * ReadFileToTextBlock
  262.  * Reads text file into text block
  263.  * File must be all ASCII
  264.  */
  265. BOOL
  266. ReadFileToTextBlock (HWND hParentWnd, TypTextBlock *block, char *fileName, int mode)
  267. {
  268.     register int i;
  269.     TypMRRFile *MRRFile;
  270.     HFILE hFile;
  271.     int numRead, result;
  272.     char mybuf[TEMPBUFSIZE];
  273.     BOOL leadingBlanks;
  274.     
  275.     hFile = MRROpenFile (fileName, OF_READ, &MRRFile);
  276.     if (hFile <= 0)
  277.     {
  278.         sprintf(str, "Could not open file %s for read", fileName);
  279.         MessageBox (hParentWnd, str, "Open File Error", MB_OK);
  280.         return (FAIL);
  281.     }
  282.     else
  283.     {
  284.         CodingState = ATTACH_READFILE;
  285.         leadingBlanks = TRUE;
  286.         result = SUCCESS;
  287.         while ((numRead = MRRReadLine (MRRFile, mybuf, TEMPBUFSIZE)) > -1)
  288.         {
  289.             mybuf[numRead] = '\0';
  290.             if (leadingBlanks)    // skip leading blanks
  291.               if (IsBlankStr (mybuf))
  292.                   continue;
  293.               else
  294.                   leadingBlanks = FALSE;
  295.                   
  296.                    for (i = 0; i < numRead; i++)
  297.             {
  298.               if (!__isascii (mybuf[i]))
  299.               {
  300.                 sprintf(str, "File %s appears to contain non-ASCII data.\nBinary files must be encoded for attachment", fileName);
  301.                 MessageBox (hParentWnd, str, "Non-ASCII File Error", MB_OK);
  302.                 result = FAIL;
  303.                 goto endRead;
  304.               }
  305.             }
  306.             if (AddEndedLineToTextBlock (block, mybuf, mode) == FAIL)
  307.                 break;
  308.             if (hCodedBlockWnd != (HWND)NULL)
  309.             {
  310.                 currentCoded->numLines++;
  311.                 currentCoded->numBytes+=numRead;
  312.                     if (currentCoded->numLines % STATUS_UPDATE_FREQ == 0)
  313.                         UpdateBlockStatus ();
  314.             }
  315.         }
  316.     }
  317.  
  318.     endRead:;
  319.     MRRCloseFile (MRRFile);
  320.     CodingState = INACTIVE;
  321.     return (result);
  322. }
  323.  
  324. /* ------------------------------------------------------------------------
  325.  * ReplaceLineInTextBlock
  326.  * This is ugly, and really inefficient of the textblock is big
  327.  * 1. If newline has length > oldline, then make sure text array has enough
  328.  *    room, then shift right the string starting at the end of oldline by 
  329.  *    n characters where n is len(newline)-len(oldline)
  330.  * 2. If newline has length < oldline then shift the string starting at the
  331.  *    end of oldline by n characters where n is len(oldline)-len(newline)
  332.  * 3. If oldline and newline are same length, do no shifting
  333.  * 4. Then copy in the new string
  334.  * 5. Adjust all affected offsets (the lines after this one) by size diff
  335.  * 6. God this is ugly, hope we don't use it much!
  336.  */                   
  337. BOOL
  338. ReplaceLineInTextBlock (TypTextBlock *textBlock, unsigned long num, char *line)
  339. {        
  340.     unsigned int newLen, oldLen;
  341.     int sizeDiff;
  342.         register char huge *dst, *src;
  343.     register unsigned long i;        
  344.     
  345.     if (line == NULL || *line == '\0')
  346.         return (SUCCESS);
  347.         
  348.     newLen = strlen (line) + 1;
  349.     oldLen = strlen(TextBlockLine(textBlock, num)) + 1;
  350.     sizeDiff = newLen - oldLen;
  351.     
  352.     if (sizeDiff > 0)    // new line longer than old line
  353.     {
  354.         // increase text array size if necessary
  355.         if (textBlock->numBytes + sizeDiff > textBlock->maxBytes)
  356.         {
  357.             textBlock->maxBytes *= 2;
  358.             if ((textBlock->text = (char huge *) GlobalReAllocPtr (textBlock->text,
  359.                         textBlock->maxBytes * sizeof (char), GMEM_MOVEABLE)) == NULL)
  360.             {
  361.                 MessageBox (textBlock->hTextWnd, "Memory Allocation Failure", "Text Block Add", ID_OK);
  362.                 return (FAIL);
  363.             }
  364.         }
  365.         // shift the text array right by sizeDiff chars
  366.         // sizeDiff iterations, walking backwards from end
  367.         for (src = textBlock->text + textBlock->numBytes,
  368.              dst = src + sizeDiff;;
  369.              dst--, src--)
  370.         {            
  371.             *dst = *src; 
  372.                  if (src == TextBlockLine(textBlock, num))
  373.                      break;
  374.         }
  375.              
  376.     }
  377.     else if (sizeDiff < 0)
  378.         // shift the text array left by sizeDiff chars
  379.         // numBytes - &oldline iterations, walking forwards
  380.         for (src = TextBlockLine(textBlock, num) + oldLen,
  381.              dst = src + sizeDiff;
  382.              dst < &textBlock->text[textBlock->numBytes + 1];
  383.              dst++, src++)
  384.             *dst = *src;
  385.     
  386.     // adjust all affected offsets (lines after this line)
  387.     if (sizeDiff != 0)
  388.         for (i = num + 1; i < textBlock->numLines; i++)
  389.             textBlock->offset[i] += sizeDiff;
  390.     
  391.     textBlock->numBytes += sizeDiff;
  392.  
  393.     // save max string len for use in scroll bar ranges in status wnd
  394.     if (newLen > textBlock->maxLineLen)
  395.         textBlock->maxLineLen = newLen;
  396.                 
  397.         // copy it in, including the NULL
  398.     memcpy (TextBlockLine(textBlock, num), line, newLen);
  399.  
  400.     return (SUCCESS);
  401. }
  402. @
  403.  
  404.  
  405. 1.4
  406. log
  407. @general cleanup for 92.6
  408. @
  409. text
  410. @d14 1
  411. a14 1
  412.  * $Id: wvtxtblk.c 1.3 1994/08/11 00:11:55 jcooper Exp $
  413. d16 3
  414. d61 1
  415. @
  416.  
  417.  
  418. 1.3
  419. log
  420. @Changes to author mail address
  421. @
  422. text
  423. @d14 1
  424. a14 1
  425.  * $Id: wvtxtblk.c 1.2 1994/05/23 18:36:00 jcooper Exp $
  426. d16 3
  427. d26 5
  428. a32 2
  429. #include <windows.h>
  430. #include <windowsx.h>
  431. a34 2
  432. #include "wvglob.h"
  433. #include "winvn.h"
  434. d222 1
  435. a222 1
  436.     HANDLE hRetCode;
  437. d227 2
  438. a228 2
  439.     hRetCode = MRROpenFile (fileName, OF_READ, &MRRFile);
  440.     if ((int) hRetCode <= 0)
  441. @
  442.  
  443.  
  444. 1.2
  445. log
  446. @new attach code, session [dis]connect
  447. @
  448. text
  449. @d10 1
  450. a10 1
  451.  * Author: John S. Cooper (jcoop@@apl.com)                           *
  452. d14 1
  453. a14 1
  454.  * $Id: wvtxtblk.c 1.1 1994/01/16 12:12:47 jcoop Exp $
  455. d16 3
  456. @
  457.  
  458.  
  459. 1.1
  460. log
  461. @Initial revision
  462. @
  463. text
  464. @d14 5
  465. a18 2
  466.  * $Id:  $
  467.  * $Log:  $
  468. d165 1
  469. a165 3
  470.  * to \n\r if posting to EditWnd, to \r if posting to net, or to \n if
  471.  * posting to dos file
  472.  * Also, if Attaching and first char is '.', change it to '..'
  473. d171 1
  474. a171 1
  475.     char *new;
  476. d176 3
  477. a178 3
  478.     new = (char *) GlobalAllocPtr (GMEM_MOVEABLE, (len+4) * sizeof(char));
  479.     if (Attaching && line[0] == '.')
  480.         new[len++] = '.';
  481. d181 1
  482. a181 1
  483.         memcpy (new, line, len);
  484. d186 1
  485. a186 1
  486.         new[len++] = '\r';    // \r if posting to net OR edit buf
  487. d190 2
  488. a191 2
  489.         new[len++] = '\r';    // to edit buf
  490.         new[len++] = '\n';
  491. d194 1
  492. a194 1
  493. //        new[len++] = '\n';
  494. d197 1
  495. a197 1
  496.     new[len] = '\0';
  497. @
  498.